package com.zzl.mq.network.gossip;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class ClusterNode {
    private String nodeId;
    private String host;
    private int port;
    private long lastHeartbeatTime;
    private NodeStatus status;
    private final RestTemplate restTemplate;
    private static final Logger log = LoggerFactory.getLogger(ClusterNode.class);
    
    public ClusterNode(String nodeId, String host, int port) {
        this.nodeId = nodeId;
        this.host = host;
        this.port = port;
        this.lastHeartbeatTime = System.currentTimeMillis();
        this.status = NodeStatus.ALIVE;
        this.restTemplate = new RestTemplate();
    }
    
    /**
     * Sends a gossip message to this cluster node.
     *
     * @param message the gossip message to send
     * @throws RuntimeException if sending the message fails
     */
    public void sendGossipMessage(GossipMessage message) {
        String url = String.format("http://%s:%d/api/gossip", host, port);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        HttpEntity<GossipMessage> request = new HttpEntity<>(message, headers);
        
        try {
            restTemplate.postForObject(url, request, ResponseEntity.class);
            // 如果发送成功，更新节点状态为 ALIVE
            this.status = NodeStatus.ALIVE;
        } catch (Exception e) {
            // 发送失败时，将节点标记为可能失效
            this.status = NodeStatus.SUSPICIOUS;
            log.error(e.getMessage());
            throw new RuntimeException("Failed to send gossip message to node: " + nodeId, e);
        }
    }
    
    public void updateHeartbeat() {
        this.lastHeartbeatTime = System.currentTimeMillis();
    }
    
    // Getters and setters
    public String getNodeId() {
        return nodeId;
    }
    
    public String getHost() {
        return host;
    }
    
    public int getPort() {
        return port;
    }
    
    public NodeStatus getStatus() {
        return status;
    }
    
    public void setStatus(NodeStatus status) {
        this.status = status;
    }
    
    public long getLastHeartbeat() {
        return lastHeartbeatTime;
    }
} 